package ws.oanda;

import java.util.HashMap;
import java.util.Map;

import model.oanda.Order;
import model.oanda.Prices;
import model.oanda.Trades;
import play.Logger;
import play.libs.F.Promise;
import play.libs.Json;
import play.libs.ws.WS;
import play.libs.ws.WSResponse;
import property.Constants;
import property.DefaultStringValue;
import property.DynamicProperty;
import property.Key;

public class WsOanda {

	//public static Promise<WSResponse> login;
	//private static long refresh = 0;

	public static Promise<WSResponse> getInstruments() {
		// if (login == null
		// || (refresh + 15 * 60 * 1000) < System.currentTimeMillis()) {
		// login =
		
		StringBuffer sbUrl=new  StringBuffer(OandaConfig.config().baseUrl());
		sbUrl.append("/v1/instruments");
		
		Logger.debug("getInstruments "+sbUrl.toString());
		
		return WS.client().url(sbUrl.toString())
				.setHeader("Authorization", OandaConfig.config().authorization())
				.setQueryParameter("accountId", OandaConfig.config().accountId())
				.setMethod("GET").execute();
		// refresh = System.currentTimeMillis();
		// }
		// return login;
	}
	
	public static Promise<Prices> getPrice(String instrument) {
		// if (login == null
		// || (refresh + 15 * 60 * 1000) < System.currentTimeMillis()) {
		// login =
		
		StringBuffer sbUrl=new  StringBuffer(OandaConfig.config().baseUrl());
		sbUrl.append("/v1/prices");
		
		Logger.debug("getPrices "+sbUrl.toString());
		
		return WS.client().url(sbUrl.toString())
				.setHeader("Authorization", OandaConfig.config().authorization())
				.setQueryParameter("accountId", OandaConfig.config().accountId())
				.setQueryParameter("instruments", instrument)
				.setMethod("GET").execute().map(resp->{ return Json.fromJson(resp.asJson(), Prices.class); });
		// refresh = System.currentTimeMillis();
		// }
		// return login;
	}
	
	public static Promise<WSResponse> makeOrder(Order order) {
		
		StringBuffer sbUrl=new  StringBuffer(OandaConfig.config().baseUrl());
		sbUrl.append("/v1/accounts/"+OandaConfig.config().accountId()+"/orders");
		
		Logger.debug("makeOrder "+sbUrl.toString());
		
		StringBuffer qs=new StringBuffer("1=1");
		Map<String, String> parameters=new HashMap<String, String>();
		parameters.put("type", "market");
		parameters.put("instrument", order.getInstrument());
		parameters.put("units", order.getUnits().toString());
		parameters.put("side", order.getSide());

		for(String s: parameters.keySet()){
			qs.append("&").append(s).append("=").append(parameters.get(s));
		}
		
		
		Promise<WSResponse> result=WS.client().url(sbUrl.toString())
				.setHeader("Authorization", OandaConfig.config().authorization())	
				.setContentType("application/x-www-form-urlencoded")
				.setBody(qs.toString())
				.setMethod("POST").execute();
		
//		return result.map(resp->{
//			return Json.fromJson(resp.asJson(), Order.class);
//		}).map(o->{
//			order.setId(o.getId());
//			return order;
//		});
		
		return result;
	}
	
	public static Promise<WSResponse> cancelOrder(Order order) {
		
		StringBuffer sbUrl=new  StringBuffer(OandaConfig.config().baseUrl());
		sbUrl.append("/v1/accounts/"+OandaConfig.config().accountId()+"/trades/"+order.getId());
		
		Logger.debug("cancelOrder "+sbUrl.toString());
				
		return WS.client().url(sbUrl.toString())
				.setHeader("Authorization", OandaConfig.config().authorization())	
				.setContentType("application/x-www-form-urlencoded")				
				.setMethod("DELETE").execute();
	}
	
	public static Promise<Trades> getTrades(){
		StringBuffer sbUrl=new  StringBuffer(OandaConfig.config().baseUrl());
		sbUrl.append("/v1/accounts/"+OandaConfig.config().accountId()+"/trades");
		
		Logger.debug("getTrades "+sbUrl.toString());
		
		return WS.client().url(sbUrl.toString())
				.setHeader("Authorization", OandaConfig.config().authorization())	
				.setContentType("application/x-www-form-urlencoded")				
				.setMethod("GET").execute().map(resp->{ return Json.fromJson(resp.asJson(), Trades.class); });
	}

	public static class OandaConfig {

		private static IOandaConfig iOandaConfig;

		private OandaConfig(){
			
		}
		
		public static IOandaConfig config() {
			if (iOandaConfig == null)
				iOandaConfig = DynamicProperty.create(IOandaConfig.class);
			return iOandaConfig;
		}

		public static interface IOandaConfig extends Constants{

			@DefaultStringValue("true")
			@Key("dev")
			boolean dev();

			@DefaultStringValue("Bearer 09d809e0c963493c9f6702917fee51df-02a690da64ae9d33946321659e766397")
			@Key("authorization")
			String authorization();

			@DefaultStringValue("https://api-fxpractice.oanda.com")
			@Key("baseUrl")
			String baseUrl();

			@DefaultStringValue("9646994")
			@Key("accountid")
			String accountId();

			@DefaultStringValue("NONE")
			@Key("trend.none")
			String trendNone();

			@DefaultStringValue("SELL")
			@Key("trend.sell")
			String trendSell();

			@DefaultStringValue("BUY")
			@Key("trend.buy")
			String trendBuy();
		}
	}

}
